package com.xiaochen.sjzremind.job;



import com.google.common.cache.Cache;
import com.xiaochen.sjzremind.common.WXResponse;
import com.xiaochen.sjzremind.common.XTCResponse;
import com.xiaochen.sjzremind.service.IAmmoPriceService;
import com.xiaochen.sjzremind.service.IRedisService;
import com.xiaochen.sjzremind.utils.DataUtil;
import com.xiaochen.sjzremind.utils.JsoupUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RSet;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import retrofit2.Call;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author xc
 * @date 2025/10/09/14:03
 * @desc 获取子弹信息
 */
@Slf4j

@Component
public class ammoInfoJob {
    
    @Resource
    private Cache<String, Integer> ammoInfoCache;
    
    @Resource
    private IAmmoPriceService ammoPriceService;
    
    @Resource
    private IRedisService redisService;

    @PostConstruct
    public void init() throws NoSuchAlgorithmException, IOException {
        updateAmmoInfo();
        queryAmmoPrice();
    }

    @Scheduled(cron = "0 0 0/1 * * ?")
    public void updateAmmoInfo(){
        if (ammoInfoCache.size() > 0) return;
        int maxPage = 8;
        //https://orzice.com/v/ammo?a=ammo&top=1-2&p=1&grade=-1&n=
        for (int i = 1; i <= maxPage; i++) {
            String url = "https://orzice.com/v/ammo?a=ammo&top=1-2&p=" + i + "&grade=-1&n=";
            String selector = "#app > div.responsive-table-container > div > div > table > tbody > tr > td.item-cell > div > a";
            Map<String, Integer> info = JsoupUtil.getAllInfo(url, selector);
            ammoInfoCache.putAll(info);
        }
    }
    
    @Scheduled(cron = "0 0/10 * * * ?")
    public void queryAmmoPrice() throws NoSuchAlgorithmException, IOException {
        // 获取当前日期时间
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String currentDate = now.format(formatter);
        //获取所有用户
        RSet<String> set = redisService.getSet("user:ids");
        //map 子弹id 用户 id
        Map<String, List<String>> map = new HashMap<>();
        for (String userId : set) {
            //查询token是否过期
            String token = (String) redisService.getValue("user:" + userId);
            if (token == null){
                //删除用户
                set.remove(userId);
                continue;
            }
            //获取要关注的弹药id
            RSet<String> ammoIdSet = redisService.getSet("user:" + userId + ":concernedAmmo");
            for(String ammoId : ammoIdSet){
                if (map.containsKey(ammoId)){
                    map.get(ammoId).add(userId);
                }else {
                    List<String> list = new ArrayList<>();
                    list.add(userId);
                    map.put(ammoId, list);
                }
            }
        }
        log.info("处理子弹和用户:{}", map);
        for (Map.Entry<String, List<String>> entry : map.entrySet()) {
            String ammoId = entry.getKey();
            List<String> userIds = entry.getValue();
            //随机获取一个token
            int index = (int) (Math.random() * userIds.size());
            String id = userIds.get(index);
            String cloud_token = (String) redisService.getValue("user:" + id);
            // 获取当前时间戳（秒）
            long timestamp = System.currentTimeMillis() / 1000;
            //生成token
            String token = DataUtil.generateSignature(ammoId, timestamp);
            //查询价格
            Integer latestPrice = (Integer) redisService.getValue("ammoId:" + ammoId + ":" + currentDate + ":latestPrice");
            Integer partialPrice = (Integer) redisService.getValue("ammoId:" + ammoId + ":" + currentDate + ":partialPrice");
            String nowPrice = null;
           //缓存查不到价格
            if (latestPrice == null){
                log.info("未获取缓存价格,查询子弹:{}", ammoId);
                Call<XTCResponse<String>> call = ammoPriceService.getLatestPrice(ammoId, token, String.valueOf(timestamp),"cloud_token=" + cloud_token);
                XTCResponse<String> body = call.execute().body();
                if (body != null && body.getData() != null){
                    //解密
                    String decrypt = DataUtil.disengageSignature(body.getData()).toString();
                    log.info("解密价格:{}", decrypt);
                    String maxRegex = "max=\\[([^\\]]+)\\]";
                    Pattern maxPattern = Pattern.compile(maxRegex);
                    Matcher maxMatcher = maxPattern.matcher(decrypt);
                    if (maxMatcher.find()){
                        String maxPrice = maxMatcher.group(1);
                        String[] split = maxPrice.split(",");
                        Integer newLatestPrice = 0;
                        Integer newPartialPrice = 0;
                        for (int i = split.length - 1, j = 0; i >= 0 && j < 7; i--, j++) {
                            if (newLatestPrice == 0){
                                newLatestPrice = Integer.valueOf(split[i].trim());
                            }else {
                                newPartialPrice = Integer.valueOf(split[i].trim()) > newLatestPrice ? Integer.valueOf(split[i].trim()) - newLatestPrice : newPartialPrice;
                                newLatestPrice = Integer.valueOf(split[i].trim()) > newLatestPrice ? Integer.valueOf(split[i].trim()) : newLatestPrice;
                               
                            }
                        }
                        //保存价格 只保存到24小时
                        redisService.setValue("ammoId:" + ammoId + ":" + currentDate + ":latestPrice", newLatestPrice,24 * 60 * 60 * 1000);
                        redisService.setValue("ammoId:" + ammoId + ":" + currentDate + ":partialPrice", newPartialPrice,24 * 60 * 60 * 1000);
                        //查询价格
                        nowPrice = isHighPrice(ammoId, token, String.valueOf(timestamp), "cloud_token=" + cloud_token, newLatestPrice,newPartialPrice);
                    }
                }
            }else { 
                //查询价格
                nowPrice = isHighPrice(ammoId, token, String.valueOf(timestamp), "cloud_token=" + cloud_token, latestPrice,partialPrice);
            }
            if (nowPrice != null){
                log.info("关注的子弹高价了，当前价格为:{}", nowPrice);
                //发送消息 在ammoInfoCache找到value为ammoId的key
                String key = ammoInfoCache.asMap().entrySet()
                        .stream()
                        .filter(e -> Objects.equals((Integer)e.getValue(), Integer.valueOf(ammoId)))
                        .findFirst()
                        .map(Map.Entry::getKey)
                        .orElse(null);
                if (key != null){
                    log.info("获取到子弹的名称:{}", key);
                    //发送消息
                    //获取推送地址并发送消息
                    for (String userId : userIds) {
                        log.info("发送消息给用户:{}", userId);
                        //获取推送地址
                        String pushSite = (String) redisService.getValue("user:" + userId + ":pushSite");
                        if (pushSite != null){
                            //发送消息
                            Call<WXResponse> pushWx = ammoPriceService.pushWx(pushSite, "弹药" + key + "价格为" + nowPrice, "弹药" + key + "价格为" + nowPrice);
                            pushWx.execute();
                        }
                    }
                    
                }
            }
        }
    }
    
    private String isHighPrice(String id, String token, String timestamp, String cookie, Integer latestPrice,Integer partialPrice) throws IOException {
       //查询实时价格
        Call<XTCResponse<String>> call = ammoPriceService.getMinutePrice(id, token, timestamp,cookie);
        XTCResponse<String> body = call.execute().body();
        if (body != null && body.getData() != null){
            //解密
            String decrypt = DataUtil.disengageSignature(body.getData()).toString();
            String bRegex = "b=\\[([^\\]]+)\\]";
            Pattern bPattern = Pattern.compile(bRegex);
            Matcher bMatcher = bPattern.matcher(decrypt);
            if (bMatcher.find()){
                String bPrice = bMatcher.group(1);
                log.info("解密实时价格:{}", bPrice);
                String[] split = bPrice.split(",");
                String nowPrice = split[split.length - 1];
                return latestPrice >= Integer.valueOf(nowPrice.trim()) + partialPrice ? null : nowPrice;
            }
        }
        return null;
        
    }
}
